package ui

import (
	"fmt"
	"os"
	"regexp"
	"ssh-connect/service"

	"github.com/AlecAivazis/survey/v2"
)

type SSHConnectUI struct {
	ConnectConfig *service.Config
}

func InitUI(config *service.Config) *SSHConnectUI {
	return &SSHConnectUI{
		ConnectConfig: config,
	}
}

func (ui *SSHConnectUI) Run() error {

	for {
		serverList := make([]string, 0)
		for name := range ui.ConnectConfig.ServerList {
			serverList = append(serverList, name)
		}

		menulist := []string{
			"添加服务器",
		}
		menulist = append(menulist, serverList...)

		// 1. 服务器列表
		// 2. 添加服务器
		var menuListUI = []*survey.Question{
			{
				Name: "",
				Prompt: &survey.Select{
					Message: "",
					Options: menulist,
					VimMode: true,
				},
			},
		}

		var selectedMenu string

		err := survey.Ask(menuListUI, &selectedMenu, survey.WithShowCursor(true))
		if err != nil {
			return err
		}

		// 服务器管理
		switch selectedMenu {
		case "添加服务器":
			if err := ui.AddServer(); err != nil {
				return err
			}
		default:
			if err := ui.OperatorServer(selectedMenu); err != nil {
				return err
			}
		}
	}
}

func (ui *SSHConnectUI) AddServer() error {
	var serverInfo service.ServerInfo
	addStep := []*survey.Question{
		{
			Name: "host",
			Prompt: &survey.Input{
				Message: "host",
			},
		},
		{
			Name: "user",
			Prompt: &survey.Input{
				Message: "user",
			},
		},
		{
			Name: "password",
			Prompt: &survey.Password{
				Message: "password",
			},
		},
	}

	err := survey.Ask(addStep, &serverInfo, survey.WithShowCursor(true))
	if err != nil {
		return err
	}

	if serverInfo.Password == "" {
		addPrivateKey := []*survey.Question{
			{
				Name: "privatekey",
				Prompt: &survey.Multiline{
					Message: "privatekey or raw data",
				},
			},
		}
		err = survey.Ask(addPrivateKey, &serverInfo, survey.WithShowCursor(true))
		if err != nil {
			return err
		}

		if serverInfo.PrivateKey != "" {
			// if !regexp.MustCompile(`-----BEGIN (RSA|EC|DSA|OPENSSH) PRIVATE KEY-----`).MatchString(serverInfo.PrivateKey) {
			if !regexp.MustCompile(`-----BEGIN (\S*) PRIVATE KEY-----`).MatchString(serverInfo.PrivateKey) {
				data, err := os.ReadFile(serverInfo.PrivateKey)
				if err != nil {
					return err
				}
				serverInfo.PrivateKey = string(data)
			}
		}
	}

	if err := ui.ConnectConfig.AddServer(&serverInfo); err != nil {
		return err
	}
	return ui.ConnectConfig.SSHConnect(serverInfo.Host)
}

func (ui *SSHConnectUI) OperatorServer(name string) error {
	var operate string
	var connect, remove, edit = "🔗连接", "➖删除", "📝编辑"
	_ = edit
	operators := []*survey.Question{
		{
			Name: "operate",
			Prompt: &survey.Select{
				Message: "操作",
				Options: []string{
					connect, remove,
				},
				VimMode: true,
			},
		},
	}
	err := survey.Ask(operators, &operate, survey.WithShowCursor(true))
	if err != nil {
		return err
	}

	switch operate {
	case connect:
		if err := ui.ConnectConfig.SSHConnect(name); err != nil {
			return err
		}
	case remove:
		if err := ui.ConnectConfig.RemoveServer(name); err != nil {
			return err
		}
	default:
		return fmt.Errorf("unsupport operator")
	}

	return nil
}
